﻿using System;
using System.Linq;
using Aso.TradingTerminalSuite.Common.Elastic;
using System.Reflection;

namespace Aso.TinyTester.Core.Configuration
{
	public static class LayoutHelper
	{
		public static ElasticObject GetLayout(object value)
		{
			if (value == null) return null;
			var saveLayout = value as ISaveLayout;
			ElasticObject result;
			var type = value.GetType();
			if (Attribute.GetCustomAttributes(type, typeof (NoLayoutAttribute), false).Length != 0)
				return null;
			if (saveLayout != null)
			{
				result = new ElasticObject();
				saveLayout.SaveLayout(result);
			}
			else
			{
				result=new ElasticObject(type.Name);
			}
			result.AddAttribute("Assembly",new ElasticObject {InternalValue = type.Assembly.GetName()});
			result.AddAttribute("Type",new ElasticObject {InternalValue = type.Name});
			var attrs = Attribute.GetCustomAttributes(type, typeof (LayoutProviderAttribute)).Cast<LayoutProviderAttribute>();
			var providers = attrs.Select(attr => Activator.CreateInstance(attr.Provider)).Cast<ILayoutProvider>();
			foreach (var provider in providers)
			{
				provider.Save(value, result);
			}

			return result;
		}

		public static object CreateFromLayout(ElasticObject layout)
		{
			var typeName = layout.GetAttributeValue("Type") as String;
			var assembly = layout.GetAttributeValue("Assembly") as String;
			if(String.IsNullOrEmpty(typeName)||String.IsNullOrEmpty(assembly))
				throw new ArgumentException("layout should have type and assembly values");
			var ass=Assembly.Load(assembly);
			var type=ass.GetType(typeName);
			var instance=Activator.CreateInstance(type, layout);
			var attrs = Attribute.GetCustomAttributes(type, typeof(LayoutProviderAttribute)).Cast<LayoutProviderAttribute>();
			var providers = attrs.Select(attr => Activator.CreateInstance(attr.Provider)).Cast<ILayoutProvider>();
			foreach (var provider in providers)
			{
				provider.Restore(instance,layout);
			}
			return instance;
		}
	}
}
